import BaseGrid from "./BaseGrid";

export default class AStar {

    static findPath(from: BaseGrid, to: BaseGrid): BaseGrid[] {
        let openGrids: BaseGrid[] = [];
        let closeGrids: BaseGrid[] = [];

        let currentGrid = from;

        currentGrid.g = 0;
        currentGrid.h = currentGrid.getCostWithGrid(to);

        openGrids.push(currentGrid);

        while (openGrids.length) {
            openGrids.sort((g1, g2) => {
                return g1.f - g2.f;
            });
            currentGrid = openGrids.shift();
            closeGrids.push(currentGrid);

            if (closeGrids.indexOf(to) != -1) {
                break;
            }

            let g = currentGrid.g + 1;
            if (!currentGrid.neighbors.length) {
                currentGrid.findNeighbors();
            }
            currentGrid.neighbors.forEach(nGrid => {

                if (nGrid.walkable == false){
                    return;
                }
                if (closeGrids.indexOf(nGrid) != -1) {
                    return;
                }

                if (openGrids.indexOf(nGrid) == -1) {
                    nGrid.g = g;
                    nGrid.h = nGrid.getCostWithGrid(to)
                    openGrids.push(nGrid);
                } else {
                    nGrid.g = Math.min(nGrid.g, g);
                }

            })
        }

        let path: BaseGrid[] = [];
        //找出路径
        if (closeGrids.indexOf(to) != -1) {
            currentGrid = to;
            path.push(currentGrid);
            for (let i = to.g - 1; i >= 0; i--) {
                currentGrid = closeGrids.filter(g => {
                    return g.g == i && g.neighbors.indexOf(currentGrid) != -1;
                })[0]
                path.push(currentGrid)
            }

        }
        return path.reverse();
    }

}